// commondef.h
#pragma once
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

#define CPPSTDEXAPI_VERSION "CPPSTDEXv1.0.4"

#define COMMON_OK 0
// 标准错误/警告//[
#define COMMON_ERR_
#define COMMON_ERR_NUKNOWN  (-1) // 未知错误
#define COMMON_ERR_NOMEM    (-2) // 内存不足
#define COMMON_ERR_INV_ARGS (-3) // 参数错误
#define COMMON_ERR_FILE     (-4) // 文件错误
#define COMMON_ERR_TIMEOUT  (-5) // 超时
#define COMMON_ERR_SOCKET   (-6) // socket错误
#define COMMON_ERR_HARDWARE (-7) // 硬件故障

#define COMMON_ERR_INV_ARG0 (-80) // 参数错误
#define COMMON_ERR_INV_ARG1 (-81) // 参数1错误
#define COMMON_ERR_INV_ARG2 (-82) // 参数2错误
#define COMMON_ERR_INV_ARG3 (-83) // 参数3错误
// 4-9省略
#define COMMON_ERR_OTHER_ARGS (-90) // 第9个之后的参数错误，也包括...语法表示的参数错误

#define COMMON_ERR_INV_ARG(n) (COMMON_ERR_INV_ARG0 - n)

#define COMMON_ERR_INVALIDARGS COMMON_ERR_INV_ARGS // 参数错误(兼容旧代码)

#define COMMON_WARN_
#define COMMON_WARN_NUKNOWN 1 // 未知警告

#define CUSTOM_ERR  (-10000) // 自定义错误
#define CUSTOM_WARN 10000    // 自定义警告
// 其它模块定义的错误/警告的绝对值需大于CUSTOM_WARN才能保证不与本模块冲突

//]

// 内存资源分配错误/警告//[
#define COMMON_ERR_INITED   (-101) // 初始化一个已被初始化的对象或（内存）池
#define COMMON_ERR_UNINITED (-102) // 使用一个未初始化的对象或（内存）池

#define COMMON_WARN_NONEED2CLEAR 101 // 对象或（内存）池无需清理
//]
// 面向对象错误/警告//[
#define COMMON_ERR_NOT_INHERITED (-201) // 父类支持但子类不支持
#define COMMON_ERR_STATE         (-202) // 操作与对象当前状态不匹配
//]

#ifndef IN
#define IN
#endif

#ifndef OUT
#define OUT
#endif

typedef char I8;
typedef unsigned char U8;
typedef unsigned char BYTE;
typedef short int I16;
typedef unsigned short int U16;
typedef int I32;
typedef unsigned int U32;
typedef void *HANDLE;

#define COMMON_CPU_BIT (sizeof(void *) * 8)

#define SET_VAR_AND_GOTO(varname, value, lable) \
    do                                          \
    {                                           \
        varname = (value);                      \
        goto lable;                             \
    } while(0)

#define SET_RET_AND_GOTO_EXIT(retvalue) SET_VAR_AND_GOTO(iRet, retvalue, _Exit)
#define GOTO_EXIT                       goto _Exit

#define COMMON_THROW_ERROR(r)                 \
    do                                        \
    {                                         \
        if((r) < 0) SET_RET_AND_GOTO_EXIT(r); \
    } while(0)

#define COMMON_THROW_WARN(r)                  \
    do                                        \
    {                                         \
        if((r) > 0) SET_RET_AND_GOTO_EXIT(r); \
    } while(0)

#define COMMON_THROW_ALL(r)                    \
    do                                         \
    {                                          \
        if((r) != 0) SET_RET_AND_GOTO_EXIT(r); \
    } while(0)

#define COMMON_THROW COMMON_THROW_ERROR

#define COERCION_AND_OPERAT(p1, p2, op, type) (*((type *)(p1))) op(*((type *)(p2)))
#define COERCION_AND_COMPARE                  COERCION_AND_OPERAT
#define COERCION_AND_ASSIGN(p1, p2, type)     COERCION_AND_OPERAT(p1, p2, =, type)

#define IS_VISIABLE_ASCII(a) (a > ' ' && a < 0x7F)

#define FREE_AND_NULL(p) \
    do                   \
    {                    \
        if(p)            \
        {                \
            free(p);     \
            p = NULL;    \
        }                \
    } while(0)

#define DELETE_AND_NULL(p) \
    do                     \
    {                      \
        if(p)              \
        {                  \
            delete(p);     \
            p = NULL;      \
        }                  \
    } while(0)

#define DELETE_ARY_AND_NULL(p) \
    do                         \
    {                          \
        if(p)                  \
        {                      \
            delete[](p);       \
            p = NULL;          \
        }                      \
    } while(0)

#define ONEHOT_ALL(a, b) (((a) & (b)) == (b)) // a包含b的所有真比特

typedef struct
{
    BYTE *data;
    int iLen;
} DATA_BLOCK; // 二进制数据块

#ifdef WINDOWS
#define COMMON_PLATFORM_DEFINED // 如果编译在此行出错，说明定义了多种平台类型
#include "windows.h"

typedef __int64 I64;
typedef unsigned __int64 U64;

#define PATH_LEN_MAX MAX_PATH

#define sleep(i)       Sleep((i) * 1000)
#define realpath(N, R) _fullpath((R), (N), MAX_PATH)
#define bzero          ZeroMemory

#define PRESS_ANY_KEY_TO_CONTINUE system("pause");

#endif // WINDOWS

#ifdef LINUX
#define COMMON_PLATFORM_DEFINED // 如果编译在此行出错，说明定义了多种平台类型
#include <limits.h>
#include <unistd.h>

typedef long long I64;
typedef unsigned long long U64;

#ifndef SOCKET
typedef int SOCKET;
#endif

#define PATH_LEN_MAX PATH_MAX

typedef struct _SYSTEMTIME
{
    U16 wYear;
    U16 wMonth;
    U16 wDayOfWeek;
    U16 wDay;
    U16 wHour;
    U16 wMinute;
    U16 wSecond;
    U16 wMilliseconds;
} SYSTEMTIME;

typedef struct _SYSTEMTIME *PSYSTEMTIME;
typedef struct _SYSTEMTIME *LPSYSTEMTIME;

#define PRESS_ANY_KEY_TO_CONTINUE              \
    cout << "Press any key to continue......"; \
    fflush(stdout);                            \
    system("read -n  1");                      \
    cout << endl;

#endif // LINUX

#ifndef COMMON_PLATFORM_DEFINED
#error platform undefined!
#endif
